import { Component, Host, h, ComponentInterface, State, Method, writeTask, Listen, Element, Prop } from '@stencil/core';
import { DataItemProvider, ListDataProvider } from '../../interface';
import { debounce } from '../../utils';

/**
 * 快捷操搜索栏
 *
 * @author chitanda
 * @date 2022-06-24 17:06:55
 * @export
 * @class QuickActionBar
 */
@Component({
  tag: 'quick-action-bar',
  styleUrl: 'quick-action-bar.scss',
  shadow: true,
})
export class QuickActionBar implements ComponentInterface {
  @Element()
  el: HTMLQuickActionBarElement;

  inputRef: HTMLInputElement;
  listRef: HTMLQuickActionListElement;

  /**
   * 操作栏是否已隐藏
   *
   * @author chitanda
   * @date 2022-07-07 14:07:20
   * @type {boolean}
   */
  @Prop()
  isHidden: boolean = true;

  /**
   * 鼠标是否悬浮在操作栏区域
   *
   * @author chitanda
   * @date 2022-07-07 14:07:30
   * @type {boolean}
   */
  @Prop()
  isHover: boolean = false;

  @State()
  searchVale: string = '';

  @State()
  isLoading: boolean = false;

  @State()
  list: DataItemProvider[] = [];

  /**
   * 列表数据适配器
   *
   * @author chitanda
   * @date 2022-06-29 14:06:14
   * @type {ListDataProvider<DataItemProvider>}
   */
  dataProvider: ListDataProvider<DataItemProvider>;

  @Listen('keydown', { target: 'document', capture: true })
  onKeydown(e: KeyboardEvent): void {
    if (this.isHidden) {
      return;
    }
    const { key } = e;
    switch (key) {
      case 'Escape':
        this.hide();
        break;
      case 'ArrowUp':
        this.listRef.up();
        break;
      case 'ArrowDown':
        this.listRef.down();
        break;
      case 'Enter':
        this.listRef.enter();
        break;
    }
  }

  /**
   * 鼠标是否悬浮在操作栏区域
   *
   * @author chitanda
   * @date 2022-07-07 14:07:51
   */
  @Listen('mouseenter')
  mouseenter(): void {
    this.el.isHover = true;
  }
  @Listen('mouseleave')
  mouseleave(): void {
    this.el.isHover = false;
  }

  /**
   * 加载列表数据
   *
   * @author chitanda
   * @date 2022-06-29 20:06:05
   * @return {*}  {Promise<void>}
   */
  async loadItems(): Promise<void> {
    if (this.dataProvider) {
      if (this.isLoading) {
        return;
      }
      const searchValue = this.searchVale;
      this.isLoading = true;
      this.list = await this.dataProvider.getItems(searchValue);
      this.isLoading = false;
      if (searchValue !== this.searchVale) {
        await this.loadItems();
      }
    }
  }

  /**
   * 显示操作栏
   *
   * @author chitanda
   * @date 2022-06-28 15:06:39
   * @return {*}  {Promise<void>}
   */
  @Method()
  async open(provider: ListDataProvider<DataItemProvider>): Promise<void> {
    this.dataProvider = provider;
    this.el.isHidden = false;
    this.loadItems();
    writeTask(() => {
      this.inputRef.focus();
    });
  }

  /**
   * 隐藏操作栏
   *
   * @author chitanda
   * @date 2022-06-28 15:06:45
   * @return {*}  {Promise<void>}
   */
  @Method()
  async hide(): Promise<void> {
    this.el.isHidden = true;
    this.reset();
  }

  /**
   * 重置组件状态及参数
   *
   * @author chitanda
   * @date 2022-06-29 16:06:29
   */
  reset(): void {
    this.searchVale = '';
  }

  /**
   * 防抖动输入
   *
   * @author chitanda
   * @date 2022-06-29 20:06:56
   */
  debounceInput = debounce(this.onInput.bind(this), 300);
  onInput(): void {
    let val = this.inputRef.value;
    if (val !== this.searchVale) {
      if (val !== '') {
        val = val.trim();
      }
      this.searchVale = val;
      this.loadItems();
    }
  }

  render() {
    return (
      <Host class={{ 'qa-bar': true, hidden: this.isHidden }}>
        <div class='qa-bar-header'>
          <div class='qa-bar-input'>
            <input
              ref={ref => (this.inputRef = ref)}
              type='text'
              value={this.searchVale}
              autoComplete='false'
              placeholder={this.dataProvider?.placeholder || '请输入想要搜索的内容'}
              onInput={this.debounceInput}
            />
            <quick-action-input-loading loading={this.isLoading} />
          </div>
        </div>
        <div class='qa-bar-list'>
          <quick-action-list ref={ref => (this.listRef = ref)} list={this.list} command={this.dataProvider?.command} />
        </div>
      </Host>
    );
  }
}
